﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace easyccms.General.HtmlHelpers
{
    /// <summary>
    /// Text box helpers.
    /// </summary>
    public static class CutomHelpers
    {
        #region Text area helper

        /// <summary>
        /// Ccs the text area.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <param name="labelName">Name of the label.</param>
        /// <param name="textBoxName">Name of the text box.</param>
        /// <returns></returns>
        public static MvcHtmlString CcTextArea(this HtmlHelper htmlHelper, string labelName, string textBoxName)
        {
            TagBuilder liBuilder = new TagBuilder("li");
            liBuilder.AddCssClass("TextArea");
            liBuilder.InnerHtml = htmlHelper.Label(labelName) + htmlHelper.TextBox(textBoxName, null).ToHtmlString();
            return MvcHtmlString.Create(liBuilder.ToString());
        }

        /// <summary>
        /// Ccs the text area.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the property.</typeparam>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <param name="expression">The expression.</param>
        /// <param name="labelClass">The label class.</param>
        /// <param name="htmlAttributes">The HTML attributes.</param>
        /// <returns></returns>
        public static MvcHtmlString CcTextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression,
            string labelClass, object htmlAttributes)
        {
            TagBuilder liBuilder = new TagBuilder("li");
            liBuilder.AddCssClass("TextArea");
            MvcHtmlString label = LabelHelper(htmlHelper,
                                              ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
                                              ExpressionHelper.GetExpressionText(expression), labelClass);

            TagBuilder divTag = new TagBuilder("div") { InnerHtml = htmlHelper.TextAreaFor(expression, htmlAttributes).ToString() };
            liBuilder.InnerHtml = label + divTag.ToString();

            return MvcHtmlString.Create(liBuilder.ToString());
        }
        


        #endregion

        #region Text box helpers

        /// <summary>
        /// Create text box line.
        /// </summary>
        /// <param name="htmlHelper">Pass along html helper.</param>
        /// <param name="labelName">Label Value.</param>
        /// <param name="textBoxName">Text Box Name.</param>
        /// <returns>Formated field line for text box input.</returns>
        public static string CcTextBox(this HtmlHelper htmlHelper, string labelName, string textBoxName)
        {
            TagBuilder liBuilder = new TagBuilder("li");
            liBuilder.AddCssClass("TextBox");
            liBuilder.InnerHtml = htmlHelper.Label(labelName) + htmlHelper.TextBox(textBoxName, null).ToHtmlString();
            return liBuilder.ToString();
        }

        /// <summary>
        /// Create text box line.
        /// </summary>
        /// <param name="htmlHelper">Pass along html helper.</param>
        /// <param name="labelName">Label Value.</param>
        /// <param name="textBoxName">Text Box Name.</param>
        /// <param name="htmlAttributes">The HTML attributes.</param>
        /// <returns>
        /// Formated field line for text box input.
        /// </returns>
        public static string CcTextBox(this HtmlHelper htmlHelper, string labelName, string textBoxName,
                                       object htmlAttributes)
        {
            TagBuilder liBuilder = new TagBuilder("li");
            liBuilder.AddCssClass("TextBox");
            liBuilder.InnerHtml = htmlHelper.Label(labelName) +
                                  htmlHelper.TextBox(textBoxName, null, htmlAttributes).ToHtmlString();
            return liBuilder.ToString();
        }

        /// <summary>
        /// Create field Line for text box.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the property.</typeparam>
        /// <param name="htmlHelper">pass along html helper.</param>
        /// <param name="expression">Expression.</param>
        /// <param name="labelClass">The label class.</param>
        /// <param name="htmlAttributes">The HTML attributes.</param>
        /// <returns>
        /// Formated Field Line.
        /// </returns>
        public static string CcTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                             Expression<Func<TModel, TProperty>> expression,
                                                             string labelClass,
                                                             object htmlAttributes)
        {
            TagBuilder liBuilder = new TagBuilder("li");


            MvcHtmlString label = LabelHelper(htmlHelper,
                                              ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
                                              ExpressionHelper.GetExpressionText(expression), labelClass);

            TagBuilder divTag = new TagBuilder("div")
                                    {InnerHtml = htmlHelper.TextBoxFor(expression, htmlAttributes).ToString()};
            liBuilder.InnerHtml = label + divTag.ToString();

            return liBuilder.ToString();
        }


        /// <summary>
        /// Create field line for drop down list.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the property.</typeparam>
        /// <param name="htmlHelper">pass along html helper.</param>
        /// <param name="expression">Expression.</param>
        /// <param name="data">Pass IEnumerable SelectListItem data.</param>
        /// <param name="labelClass">The label class.</param>
        /// <returns>
        /// Formated Field Line.
        /// </returns>
        public static string CcDropDownFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                              Expression<Func<TModel, TProperty>> expression,
                                                              IEnumerable<SelectListItem> data, string labelClass,
                                                              object htmlAttributes)
        {
            TagBuilder liBuilder = new TagBuilder("li");

            MvcHtmlString label = LabelHelper(htmlHelper,
                                              ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
                                              ExpressionHelper.GetExpressionText(expression), labelClass);
            TagBuilder divTag = new TagBuilder("div")
                                    {
                                        InnerHtml = htmlHelper.DropDownListFor(expression, data, htmlAttributes).ToString()
                                    };
            liBuilder.InnerHtml = label + divTag.ToString();

            return liBuilder.ToString();
        }

        #endregion

        #region Label extension

        /// <summary>
        /// Labels the helper.
        /// </summary>
        /// <param name="html">The HTML.</param>
        /// <param name="metadata">The metadata.</param>
        /// <param name="htmlFieldName">Name of the HTML field.</param>
        /// <param name="labelClass">The label class.</param>
        /// <param name="extraText">The extra text.</param>
        /// <param name="id">The id.</param>
        /// <param name="generatedId">if set to <c>true</c> [generated id].</param>
        /// <returns>Formated label helper tag.</returns>
        private static MvcHtmlString LabelHelper(this HtmlHelper html, ModelMetadata metadata, string htmlFieldName,
                                                 string labelClass = null, string extraText = null, string id = null,
                                                 bool generatedId = false)
        {
            string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();

            if (String.IsNullOrEmpty(labelText)) return MvcHtmlString.Empty;

            var sb = new StringBuilder();

            sb.Append(labelText);
            sb.Append(extraText);

            TagBuilder tag = new TagBuilder("label");
            if (!String.IsNullOrEmpty(labelClass)) tag.AddCssClass(labelClass);

            if (!string.IsNullOrWhiteSpace(id))
            {
                tag.Attributes.Add("id", id);
            }
            else if (generatedId)
            {
                tag.Attributes.Add("id",
                                   html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName) + "_Label");
            }

            tag.SetInnerText(sb.ToString());

            return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
        }

        #endregion
    }
}
